from django.db import models

# Create your models here.

from django.db import models
from django.contrib.auth.models import AbstractUser
from utils.models import CoreModel
from utils.enums import OperationMethod, OperationObject
from utils.request import get_request_data, get_request_path, get_request_ip


class Users(AbstractUser, CoreModel):
    username = models.CharField(
        max_length=150,
        unique=True,
        db_index=True,
        verbose_name="用户账号",
        help_text="用户账号",
    )
    email = models.EmailField(
        max_length=255, verbose_name="邮箱", null=True, blank=True, help_text="邮箱"
    )
    mobile = models.CharField(
        max_length=255, verbose_name="电话", null=True, blank=True, help_text="电话"
    )
    avatar = models.TextField(verbose_name="头像", null=True, blank=True, help_text="头像")
    name = models.CharField(max_length=40, verbose_name="姓名", help_text="姓名")
    status = models.BooleanField(default=True, verbose_name="状态", help_text="状态")
    GENDER_CHOICES = (
        (0, "女"),
        (1, "男"),
    )
    gender = models.IntegerField(
        choices=GENDER_CHOICES,
        default=1,
        verbose_name="性别",
        null=True,
        blank=True,
        help_text="性别",
    )
    role = models.ManyToManyField(
        to="Role", verbose_name="关联角色", db_constraint=False, help_text="关联角色"
    )
    first_name = models.CharField(max_length=150, blank=True, null=True)
    last_name = models.CharField(max_length=150, blank=True, null=True)

    class Meta:
        db_table = "system_users"
        verbose_name = "用户表"
        verbose_name_plural = verbose_name
        ordering = ("-create_time",)

    def __str__(self) -> str:
        return self.username


class Role(CoreModel):
    name = models.CharField(max_length=64, verbose_name="角色名称", help_text="角色名称")
    code = models.CharField(
        max_length=64, unique=True, verbose_name="角色编码", help_text="角色编码"
    )
    status = models.BooleanField(default=True, verbose_name="角色状态", help_text="角色状态")

    class Meta:
        db_table = "system_role"
        verbose_name = "角色表"
        verbose_name_plural = verbose_name
        ordering = ("-create_time",)

    # 显示名称
    def __str__(self):
        return self.name


class Api(CoreModel):
    path = models.CharField(
        max_length=255, null=True, blank=True, verbose_name="api路径", help_text="api路径"
    )
    desc = models.CharField(max_length=255, verbose_name="api说明", help_text="api说明")
    api_group = models.CharField(
        max_length=255, default="api组", verbose_name="api组", help_text="api组"
    )
    METHOD_CHOICES = (
        (0, "GET"),
        (1, "POST"),
        (2, "PUT"),
        (3, "DELETE"),
    )
    method = models.IntegerField(
        choices=METHOD_CHOICES,
        default=0,
        verbose_name="api请求方法",
        null=True,
        blank=True,
        help_text="api请求方法",
    )

    class Meta:
        db_table = "system_api"
        verbose_name = "api表"
        verbose_name_plural = verbose_name
        ordering = ("-create_time",)


class OperationLog(CoreModel):
    request_username = models.CharField(
        max_length=50, blank=True, null=True, verbose_name="请求用户", help_text="请求用户"
    )
    request_modular = models.CharField(
        max_length=64, verbose_name="请求模块", null=True, blank=True, help_text="请求模块"
    )
    request_path = models.CharField(
        max_length=400, verbose_name="请求地址", null=True, blank=True, help_text="请求地址"
    )
    request_body = models.TextField(
        verbose_name="请求参数", null=True, blank=True, help_text="请求参数"
    )
    request_method = models.CharField(
        max_length=8, verbose_name="请求方式", null=True, blank=True, help_text="请求方式"
    )
    request_msg = models.TextField(
        verbose_name="操作说明", null=True, blank=True, help_text="操作说明"
    )
    request_ip = models.CharField(
        max_length=32, verbose_name="请求ip地址", null=True, blank=True, help_text="请求ip地址"
    )
    request_browser = models.CharField(
        max_length=64, verbose_name="请求浏览器", null=True, blank=True, help_text="请求浏览器"
    )
    response_code = models.CharField(
        max_length=32, verbose_name="响应状态码", null=True, blank=True, help_text="响应状态码"
    )
    request_os = models.CharField(
        max_length=64, verbose_name="操作系统", null=True, blank=True, help_text="操作系统"
    )
    json_result = models.TextField(
        verbose_name="返回信息", null=True, blank=True, help_text="返回信息"
    )
    status = models.BooleanField(default=False, verbose_name="响应状态", help_text="响应状态")

    class Meta:
        db_table = "system_operation_log"
        verbose_name = "操作日志"
        verbose_name_plural = verbose_name
        ordering = ("-create_time",)


class SimpleOperationLog(CoreModel):
    user_id = models.IntegerField(verbose_name="用户ID", help_text="用户ID")
    object_cls = models.CharField(
        max_length=255, verbose_name="操作对象类", help_text="操作对象类"
    )
    method = models.CharField(max_length=255, verbose_name="操作方法", help_text="操作方法")
    ip = models.CharField(
        null=True, max_length=32, verbose_name="访问IP", help_text="访问IP"
    )
    detail = models.JSONField(verbose_name="详细参数", help_text="详细参数")

    class Meta:
        db_table = "system_simple_operation_log"
        verbose_name = "简要操作"
        verbose_name_plural = verbose_name
        ordering = ("-create_time",)

    @classmethod
    def add_log(
        cls,
        request,
        user_id: int,
        object_cls: OperationObject,
        method: OperationMethod,
        remark: str,
    ):
        ip = get_request_ip(request)
        body = get_request_data(request)
        path = get_request_path(request)
        data = {
            "user_id": user_id,
            "object_cls": object_cls.value,
            "method": method.value,
            "ip": ip,
            "remark": remark,
            "detail": {
                "target_url": path,
                "user_agent": request.headers.get("user-agent"),
                "method": request.method,
                "body": body,
            },
        }
        cls.objects.create(**data)
